/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package ru.staf.NetworkReportGenerator.V2;

import ru.staf.NetworkReportGenerator.*;
import java.util.HashMap;

/**
 *
 * @author aezhov
 */
public class DeviceMacRegistry {
    static DeviceMacRegistry instance = null;
    HashMap<String, String> registry = new HashMap<String, String>();
    HashMap<String, DeviceFactory> readyFactories = new HashMap<String, DeviceFactory>();
    FakeFactory fakeFactory = new FakeFactory();

    private DeviceMacRegistry() {
        String stdPanasonicFactoryClassname = 
                "ru.staf.NetworkReportGenerator.V2.PanasonicFactory";
        String stdAsusFactoryClassname =
                "ru.staf.NetworkReportGenerator.V2.AsusFactory";
        
        // Panasonic district
        registry.put("00:0F:12", stdPanasonicFactoryClassname);
        registry.put("00:19:87", stdPanasonicFactoryClassname);
        registry.put("00:1B:D3", stdPanasonicFactoryClassname);
        registry.put("00:20:D9", stdPanasonicFactoryClassname);
        registry.put("00:50:40", stdPanasonicFactoryClassname);
        registry.put("00:80:F0", stdPanasonicFactoryClassname);
        registry.put("00:C0:8F", stdPanasonicFactoryClassname);
        registry.put("00:D0:60", stdPanasonicFactoryClassname);
        registry.put("04:20:9A", stdPanasonicFactoryClassname);
        registry.put("08:00:23", stdPanasonicFactoryClassname);
        registry.put("30:4C:7E", stdPanasonicFactoryClassname);
        registry.put("70:58:12", stdPanasonicFactoryClassname);
        registry.put("CC:7E:E7", stdPanasonicFactoryClassname);
        registry.put("D8:B1:2A", stdPanasonicFactoryClassname);
        registry.put("E0:EE:1B", stdPanasonicFactoryClassname);
        registry.put("00:00:EB", stdPanasonicFactoryClassname);
        registry.put("00:0B:97", stdPanasonicFactoryClassname);
        registry.put("00:0D:2E", stdPanasonicFactoryClassname);
        registry.put("00:10:1E", stdPanasonicFactoryClassname);
        registry.put("00:12:67", stdPanasonicFactoryClassname);
        registry.put("00:13:43", stdPanasonicFactoryClassname);
        registry.put("00:1B:D3", stdPanasonicFactoryClassname);
        registry.put("00:80:45", stdPanasonicFactoryClassname);
        registry.put("00:E0:5C", stdPanasonicFactoryClassname);

        // ASUS district
        registry.put("00:04:0F", stdAsusFactoryClassname);
        registry.put("00:0C:6E", stdAsusFactoryClassname);
        registry.put("00:0E:A6", stdAsusFactoryClassname);
        registry.put("00:11:2F", stdAsusFactoryClassname);
        registry.put("00:11:D8", stdAsusFactoryClassname);
        registry.put("00:13:D4", stdAsusFactoryClassname);
        registry.put("00:15:F2", stdAsusFactoryClassname);
        registry.put("00:17:31", stdAsusFactoryClassname);
        registry.put("00:18:F3", stdAsusFactoryClassname);
        registry.put("00:1A:92", stdAsusFactoryClassname);
        registry.put("00:1B:FC", stdAsusFactoryClassname);
        registry.put("00:1D:60", stdAsusFactoryClassname);
        registry.put("00:1E:8C", stdAsusFactoryClassname);
        registry.put("00:1F:C6", stdAsusFactoryClassname);
        registry.put("00:22:15", stdAsusFactoryClassname);
        registry.put("00:23:54", stdAsusFactoryClassname);
        registry.put("00:24:8C", stdAsusFactoryClassname);
        registry.put("00:26:18", stdAsusFactoryClassname);
        registry.put("00:E0:18", stdAsusFactoryClassname);
        registry.put("14:DA:E9", stdAsusFactoryClassname);
        registry.put("20:CF:30", stdAsusFactoryClassname);
        registry.put("48:5B:39", stdAsusFactoryClassname);
        registry.put("54:04:A6", stdAsusFactoryClassname);
        registry.put("90:E6:BA", stdAsusFactoryClassname);
        registry.put("BC:AE:C5", stdAsusFactoryClassname);
        registry.put("E0:CB:4E", stdAsusFactoryClassname);
        registry.put("F4:6D:04", stdAsusFactoryClassname);
    }

    public static synchronized DeviceMacRegistry getRegistry() {
        if (instance == null)
            return (instance = new DeviceMacRegistry());
        else
            return instance;
    }

    // Public inteface
    public DeviceFactory getDeviceFactory(String mac) {
        String[] parts = mac.split(":");
        String vendorId = parts[0] + ":" + parts[1] + ":" + parts[2];
        String factoryName = registry.get(vendorId);
        if (factoryName != null) {
            System.out.println("DeviceRegistry: we need following factory " + factoryName);
            try {
                DeviceFactory df = readyFactories.get(factoryName);
                if (df == null) {
                    df = (DeviceFactory)Class.forName(factoryName).newInstance();
                    readyFactories.put(factoryName, df);
                }

                System.out.println("OK");
                return df;
            } catch (Exception exc) {
                System.out.println("=== DeviceRgistry: working without device info: " + exc);
                return fakeFactory;
            }
        }  else {
            System.out.println("DeviceRegistry: can found appropriate device factory");
            return fakeFactory;
        }
    }
 }
